package org.yagnus.stats.sampler;


/**
 *
 * @author hc.busy
 * 
 * This class containing things shared by all samplers implemented here.
 * Derived abstract subclasses should set policies on if further 
 * derived classes should use the shared RNG or a separate one 
 * or a separate one each time.
 * 
 */
public abstract class Sampler {

    private static final ThreadLocal<RandomNumberGenerator> _rng =
            new ThreadLocal<RandomNumberGenerator>() {

                @Override
                final protected RandomNumberGenerator initialValue() {
                    return new UnsynchronizedJavaRandom();
                    //alternatively return new JavaUtilRandom();
                }
            };
    private RandomNumberGenerator _my_rng = null;

    /**
     * all methods in this and derived classes should call this function to obtain the source of entropy
     * @return
     */
    public final RandomNumberGenerator rng() {
        if (_my_rng == null) {
            return _rng.get();
        } else {
            return _my_rng;
        }
    }

    public Sampler(UnsynchronizedJavaRandom r) {
        _my_rng = r;
    }

    public Sampler() {
        _my_rng = null;
    }

    /**
     * Specify a source of entropy
     * @param r
     */
    public final void setRng(UnsynchronizedJavaRandom r) {
        _my_rng = r;
    }

    /**
     * Seed, if possible the source of entropy
     * @param seed
     * @return true if the Random class was reseeded.
     */
    public final boolean reseed(int seed) {
        if (_my_rng != null) {
            _my_rng.setSeed(seed);
            return true;
        }
        return false;
    }

    /**
     * Set the seed for the thread local randomizer.
     * @param seed
     * @return
     */
    public static boolean reseedThreadLocalRng(int seed) {
        _rng.get().setSeed(seed);
        return true;
    }
}
